/*
 * Copyright 2024 Hangzhou Yingyi Technology Co., Ltd
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <arm/arm64/pagetable.S>

#include <uk/config.h>
#include <uk/reloc.h>
/* ------------------------- Memory Map of raspi  -----------------------
 *
 * 0x0000000000000 - 0x000003EFFFFFF NormalMem: 0-1008M          attr:normal
 * 0x000003F000000 - 0x000003FFFFFFF Device:    1008MiB-1024MiB  attr:device
 * 0x0000040000000 - 0x00000401FFFFF Peripheral:1024MiB-1026MiB  attr:device
 *
 * Notice: The page tables below use the Unikraft indexing convention.
 */

.section .data
.align 4
.global bpt_unmap_mrd
bpt_unmap_mrd:
	.quad	0x000000000001000		/* 4K */
	.quad	0x000000000001000		/* 4k */
	/* Used for struct ukplat_memregion_desc
	 * Unmapping starts at 4K and ends at 1G
	 */
	.quad	0x000000003EFFF000
	.short	0x0000000000000000
	.short	0x0000000000000010		/* UKPLAT_MEMRF_UNMAP */
	.space	36

.global arm64_bpt_l3_pt0
/* L3: 0 - 256TiB (512GiB / entry)
 *
 * 0x0000000000000 - 0x0007fffffffff	Table descriptor to l2_pt0
 * 0x0008000000000 - 0x0FF7FFFFFFFFF	Unmapped
 * 0x0ff8000000000 - 0x0ffffffffffff	Table descriptor to l2_pt511
 */
.align 12
arm64_bpt_l3_pt0:
	ur_pte  arm64_bpt_l2_pt0, PTE_TYPE_TABLE
 	pte_zero	, 510
#if CONFIG_PAGING
	ur_pte  arm64_bpt_l2_pt511, PTE_TYPE_TABLE
#else /* !CONFIG_PAGING */
	pte_zero	, 1
#endif /* !CONFIG_PAGING */

/* L2: 0 - 512GiB (1GiB / entry)
 *
 * 0x0000000000000000 - 0x000000003FFFFFFF	Table descriptor to l1_pt0
 * 0x0000000040000000 - 0x000000007FFFFFFF	Table descriptor to l1_pt1
 * 0x0000000080000000 - 0x0000007FFFFFFFFF	Unmapped
 */
.align 12
arm64_bpt_l2_pt0:
	ur_pte  arm64_bpt_l1_pt0, PTE_TYPE_TABLE
	ur_pte  arm64_bpt_l1_pt1, PTE_TYPE_TABLE
	pte_zero	,510

#if CONFIG_PAGING
/* L2: 255.5 TiB - 256TiB (1GiB / entry)
 *
 * 0x0000ff8000000000 - 0x0000ffffffffffff	Direct-mapped
 */
.align 12
arm64_bpt_l2_pt511:
	pte_fill	0x0000000000000000, 1, 2, PTE_BLOCK_NORMAL_RW
	pte_zero	, 511
#endif /* CONFIG_PAGING */

/* L1: 0 - 1GiB (2MiB / entry)
 * 0x0000000000 - 0x00003EFFFFFF  NormalMem 948M    - 1008MiB      attr：normal
 * 0x003F000000 - 0x00003FFFFFFF  Device:   1008MiB - 1024MiB	   attr: device
 * There could be an arm64_bpt_l0_pt0,but it has no attribute difference
 * from arm64_bpt_l1_pt0's first page,and 512 entries of 2MiB will cover all
 * raspi memory,so it is not necessary for an arm64_bpt_l0_pt0.
 */
.align 12
arm64_bpt_l1_pt0:
	pte_fill	0x0000000000000000, 504, 1, PTE_BLOCK_NORMAL_RWX
	pte_fill	0x000000003F000000, 8, 1, PTE_BLOCK_DEVICE_nGnRnE

/* L1: 1 - 2GiB (2MiB / entry)(0-2Mi covered by arm64_bpt_l0_pt0 )
 * 0x0000000040000000 - 0x00007fffffff  device    @1GiB                 device
 */
.align 12
arm64_bpt_l1_pt1:
	pte_fill	0x0000000040000000, 1, 1, PTE_BLOCK_DEVICE_nGnRnE
	pte_zero	, 511
